package com.ruoyi.odorservice.controller;


import com.ruoyi.common.core.domain.Result;
import com.ruoyi.odorservice.model.bean.SiteMaterialConcentrationBean;
import com.ruoyi.odorservice.model.vo.MaterialTotalTrendVo;
import com.ruoyi.odorservice.model.vo.OdorActivityAnalysisVo;
import com.ruoyi.odorservice.model.vo.OdorousMaterialVo;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.odorservice.model.vo.*;
import com.ruoyi.odorservice.service.AnalysisService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.List;

@RestController
@RequestMapping("/analysis")
@Api(tags = "分析信息")
@AllArgsConstructor
@Slf4j
public class AnalysisController {

    private AnalysisService analysisService;

    @GetMapping("/totalTrend")
    @ApiOperation(value = "总量趋势分析",httpMethod = "GET", response = MaterialTotalTrendVo.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "String", required = false),
            @ApiImplicitParam(name = "endTime", value = "时间结尾", paramType = "query", dataType = "String", required = false),
            @ApiImplicitParam(name = "siteName", value = "点位名称", paramType = "query", dataType = "String", required = false)
    })
    public Result<List<MaterialTotalTrendVo>> totalTrend(@RequestParam(value = "startTime", required = false) String startTime,
                                                         @RequestParam(value = "endTime", required = false) String endTime,
                                                         @RequestParam(value = "siteName", required = false) String siteName) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime start = null;
        LocalDateTime end = null;
        //判断开始和结束时间格式，如果为空，则给默认值
        try{
            start = (startTime != null) ? LocalDateTime.parse(startTime, formatter) : LocalDateTime.parse("1900-01-01 00:00:00", formatter);
        } catch (DateTimeParseException e) {
            log.error("开始时间格式有误" + startTime, e);
            return Result.fail("开始时间输入格式不正确，请输入正确的时间格式（yyyy-MM-dd HH:mm:ss）");
        }
        try{
            end = (endTime != null) ? LocalDateTime.parse(endTime, formatter) : LocalDateTime.parse("2900-01-01 00:00:00", formatter);
        } catch (DateTimeParseException e) {
            log.error("结束时间格式有误" + startTime, e);
            return Result.fail("结束时间输入格式不正确，请输入正确的时间格式（yyyy-MM-dd HH:mm:ss）");
        }
        List<MaterialTotalTrendVo> materialTotalTrendVoList = analysisService.totalTrend(start, end, siteName);
        return Result.ok(materialTotalTrendVoList);
    }

    @GetMapping("/odorActivityAnalysis")
    @ApiOperation(value = "气味活度分析",httpMethod = "GET", response = OdorActivityAnalysisVo.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "String", required = false),
            @ApiImplicitParam(name = "endTime", value = "时间结尾", paramType = "query", dataType = "String", required = false),
            @ApiImplicitParam(name = "siteName", value = "点位名称", paramType = "query", dataType = "String", required = false)
    })
    public Result<List<OdorActivityAnalysisVo>> odorActivity(@RequestParam(value = "startTime", required = false) String startTime,
                                                             @RequestParam(value = "endTime", required = false) String endTime,
                                                             @RequestParam(value = "siteName", required = false) String siteName) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime start = null;
        LocalDateTime end = null;
        //判断开始和结束时间格式，如果为空，则给默认值
        try{
            start = (startTime != null) ? LocalDateTime.parse(startTime, formatter) : LocalDateTime.parse("1900-01-01 00:00:00", formatter);
        } catch (DateTimeParseException e) {
            log.error("开始时间格式有误" + startTime, e);
            return Result.fail("开始时间输入格式不正确，请输入正确的时间格式（yyyy-MM-dd HH:mm:ss）");
        }
        try{
            end = (endTime != null) ? LocalDateTime.parse(endTime, formatter) : LocalDateTime.parse("2900-01-01 00:00:00", formatter);
        } catch (DateTimeParseException e) {
            log.error("结束时间格式有误" + startTime, e);
            return Result.fail("结束时间输入格式不正确，请输入正确的时间格式（yyyy-MM-dd HH:mm:ss）");
        }
        List<OdorActivityAnalysisVo> odorActivityAnalysisVoList = analysisService.odorActivity(start, end, siteName);
        return Result.ok(odorActivityAnalysisVoList);
    }

    @GetMapping("/relevanceAnalysis")
    @ApiOperation(value = "相关性分析",httpMethod = "GET", response = CorrelationAnalysisVo.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "String", required = false),
            @ApiImplicitParam(name = "endTime", value = "时间结尾", paramType = "query", dataType = "String", required = false),
            @ApiImplicitParam(name = "siteName", value = "点位名称", paramType = "query", dataType = "String", required = false)
    })
    public Result<List<CorrelationAnalysisVo>> relevanceAnalysis(@RequestParam(value = "startTime", required = false) String startTime,
                                                               @RequestParam(value = "endTime", required = false) String endTime,
                                                               @RequestParam(value = "siteName", required = false) String siteName) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime start = null;
        LocalDateTime end = null;
        //判断开始和结束时间格式，如果为空，则给默认值
        try{
            start = (startTime != null) ? LocalDateTime.parse(startTime, formatter) : LocalDateTime.parse("1900-01-01 00:00:00", formatter);
        } catch (DateTimeParseException e) {
            log.error("开始时间格式有误" + startTime, e);
            return Result.fail("开始时间输入格式不正确，请输入正确的时间格式（yyyy-MM-dd HH:mm:ss）");
        }
        try{
            end = (endTime != null) ? LocalDateTime.parse(endTime, formatter) : LocalDateTime.parse("2900-01-01 00:00:00", formatter);
        } catch (DateTimeParseException e) {
            log.error("结束时间格式有误" + startTime, e);
            return Result.fail("结束时间输入格式不正确，请输入正确的时间格式（yyyy-MM-dd HH:mm:ss）");
        }
        siteName = (siteName != null) ? siteName : "点位1";
        List<CorrelationAnalysisVo> relevanceAnalysisVoList = analysisService.relevanceAnalysis(start, end, siteName);
        return Result.ok(relevanceAnalysisVoList);
    }

    @GetMapping("/odorousMaterialList")
    @ApiOperation(value = "致臭物质名单",httpMethod = "GET", response = OdorousMaterialVo.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页码", paramType = "query", dataType = "Integer" , required = false),
            @ApiImplicitParam(name = "limit", value = "每页数量", paramType = "query", dataType = "Integer" , required = false),
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "String", required = false),
            @ApiImplicitParam(name = "endTime", value = "时间结尾", paramType = "query", dataType = "String", required = false),
            @ApiImplicitParam(name = "siteName", value = "点位名称", paramType = "query", dataType = "String", required = false)
    })
    public Result<OdorousMaterialVo> odorousMaterialList(@RequestParam(value ="page", defaultValue = "1", required = false) Integer page,
                                             @RequestParam(value ="limit", defaultValue = "10", required = false) Integer limit,
                                             @RequestParam(value = "startTime", required = false) String startTime,
                                             @RequestParam(value = "endTime", required = false) String endTime,
                                             @RequestParam(value = "siteName", required = false) String siteName) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime start = null;
        LocalDateTime end = null;
        //判断开始和结束时间格式，如果为空，则给默认值
        try{
            start = (startTime != null) ? LocalDateTime.parse(startTime, formatter) : LocalDateTime.parse("1900-01-01 00:00:00", formatter);
        } catch (DateTimeParseException e) {
            log.error("开始时间格式有误" + startTime, e);
            return Result.fail("开始时间输入格式不正确，请输入正确的时间格式（yyyy-MM-dd HH:mm:ss）");
        }
        try{
            end = (endTime != null) ? LocalDateTime.parse(endTime, formatter) : LocalDateTime.parse("2900-01-01 00:00:00", formatter);
        } catch (DateTimeParseException e) {
            log.error("结束时间格式有误" + startTime, e);
            return Result.fail("结束时间输入格式不正确，请输入正确的时间格式（yyyy-MM-dd HH:mm:ss）");
        }
        OdorousMaterialVo odorousMaterialVo = analysisService.odorousMaterialList(page, limit, start, end, siteName);
        return Result.ok(odorousMaterialVo);
    }

    @GetMapping("/export/odorousMaterialList")
    @ApiOperation(value = "导出致臭物质名单Excel", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "endTime", value = "时间结尾", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "siteName", value = "点位名称", paramType = "query", dataType = "String")
    })
    public void getOdorousMaterialListExcel(@RequestParam(value = "startTime", required = false) String startTime,
                                            @RequestParam(value = "endTime", required = false) String endTime,
                                            @RequestParam(value = "siteName", required = false) String siteName,
                                            HttpServletResponse response) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime start = null;
        LocalDateTime end = null;
        //判断开始和结束时间格式，如果为空，则给默认值
        try{
            start = (startTime != null) ? LocalDateTime.parse(startTime, formatter) : LocalDateTime.parse("1900-01-01 00:00:00", formatter);
        } catch (DateTimeParseException e) {
            log.error("开始时间格式有误" + startTime, e);
            return;
        }
        try{
            end = (endTime != null) ? LocalDateTime.parse(endTime, formatter) : LocalDateTime.parse("2900-01-01 00:00:00", formatter);
        } catch (DateTimeParseException e) {
            log.error("结束时间格式有误" + startTime, e);
            return;
        }
        Integer page = 1;
        Integer limit = 10000000;
        List<OdorousMaterialVo.OdorousMaterial> odorousMaterialList = analysisService.getOdorousMaterialListExcel(start, end, page, limit, siteName);
        ExcelUtil<OdorousMaterialVo.OdorousMaterial> excelUtil = new ExcelUtil<>(OdorousMaterialVo.OdorousMaterial.class);
        excelUtil.exportExcel(response, odorousMaterialList, "致臭物质名单");
    }

    @GetMapping("/siteComparisonAnalysis")
    @ApiOperation(value = "点位比较分析",httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "endTime", value = "时间结尾", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "siteName", value = "点位名称", paramType = "query", dataType = "String")
    })
    public Result<List<SiteComparisonVo>> siteComparisonAnalysis (@RequestParam(value = "startTime", defaultValue = "2000-01-01 00:00:00") String startTime,
                                                                  @RequestParam(value = "endTime", defaultValue = "2999-01-01 00:00:00") String endTime,
                                                                  String siteName) {
        return analysisService.siteComparisonAnalysis(startTime, endTime, siteName);
    }

    @GetMapping("/concentrationContributions")
    @ApiOperation(value = "物质浓度贡献排名", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "endTime", value = "时间结尾", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "siteName", value = "点位名称", paramType = "query", dataType = "String")
    })
    public Result<ConcentrationContributionVo> concentrationContributions(@RequestParam(value = "startTime", defaultValue = "2000-01-01 00:00:00") String startTime,
                                                                          @RequestParam(value = "endTime", defaultValue = "2999-01-01 00:00:00") String endTime,
                                                                          Integer page, Integer limit, String siteName) {

        if(page == null) page = 1;
        if(limit == null) limit = 100000000;

        return analysisService.concentrationContributions(startTime, endTime, siteName, page, limit);
    }

    @GetMapping("/export/concentrationContributions")
    @ApiOperation(value = "导出物质浓度贡献排名Excel", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "endTime", value = "时间结尾", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "siteName", value = "点位名称", paramType = "query", dataType = "String")
    })
    public void getConcentrationContributionsExcel(@RequestParam(value = "startTime", defaultValue = "2000-01-01 00:00:00") String startTime,
                                                   @RequestParam(value = "endTime", defaultValue = "2999-01-01 00:00:00") String endTime,
                                                   HttpServletResponse response, String siteName) {
        Integer page = 1;
        Integer limit = 10000000;
        List<ConcentrationContributionVo.SimpleMaterial> materialList = analysisService.getConcentrationContributionsExcel(startTime, endTime, page, limit, siteName);
        ExcelUtil<ConcentrationContributionVo.SimpleMaterial> excelUtil = new ExcelUtil<>(ConcentrationContributionVo.SimpleMaterial.class);
        excelUtil.exportExcel(response, materialList, "物质浓度贡献排名");
    }


    @GetMapping("/odorProfile")
    @ApiOperation(value = "点位气味轮廓图", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "endTime", value = "时间结尾", paramType = "query", dataType = "String")
    })
    public Result<List<OdorProfileVo>> odorProfile(@RequestParam(value = "startTime", defaultValue = "2000-01-01 00:00:00") String startTime,
                                             @RequestParam(value = "endTime", defaultValue = "2999-01-01 00:00:00") String endTime) {

        return analysisService.odorProfile(startTime, endTime);
    }

    @GetMapping("/clusterAnalysis")
    @ApiOperation(value = "聚类分析", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "endTime", value = "时间结尾", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "clusterNum", value = "簇数量", paramType = "query", dataType = "Integer")
    })
    public Result<ClusterAnalysisVo> clusterAnalysis (@RequestParam(value = "startTime", defaultValue = "2000-01-01 00:00:00") String startTime,
                                                      @RequestParam(value = "endTime", defaultValue = "2999-01-01 00:00:00") String endTime,
                                                      @RequestParam(value = "clusterNum", defaultValue = "2") Integer clusterNum) {

        ClusterAnalysisVo clusterAnalysisVo = analysisService.clusterAnalysis(startTime, endTime, clusterNum);
        return Result.ok(clusterAnalysisVo);
    }
}
